package com.ttx.http.demo.manager;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.ttx.http.demo.config.LoggingRequestInterceptor;
import com.ttx.http.demo.config.RestTemplateConfig;
import com.ttx.http.demo.model.rest.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.PostConstruct;
import java.net.URI;
import java.util.Arrays;
import java.util.Map;

/**
 * @author TimFruit
 * @date 19-12-30 下午7:06
 */
@Component
@Slf4j
public class RestTemplateManager {
    @Autowired
    private RestTemplateConfig config;
    private RestTemplate restTemplate;


    private String SERVER_PREFIX;

    @PostConstruct
    public void init(){
        restTemplate=new RestTemplate();
        //使用fastjson转换json
        restTemplate.getMessageConverters().add(0, new FastJsonHttpMessageConverter());
        //打印调试日志
        restTemplate.setInterceptors(Arrays.asList(new LoggingRequestInterceptor()));

        SERVER_PREFIX=config.getUrl();
    }

    /**
     * get请求
     * @param requestDto
     */
    public GetExampleDataDto getExample(GetExampleRequestDto requestDto){
        String url=SERVER_PREFIX+"/get-example?userId={userId}&age={age}";
        try{
            //请求参数
            Map vars=(JSONObject)JSON.toJSON(requestDto);
            ResponseEntity<String>  entity=restTemplate.getForEntity(url, String.class, vars);
            Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
            GetExampleDataDto dataDto=getData(entity.getBody(), GetExampleDataDto.class);
            return dataDto;
        }catch (Exception e){
            String message="请求url: "+url+"出错";
            log.error(message, e);
            log.error("请求参数: {}", JSON.toJSON(requestDto));
            throw new RuntimeException(message, e);
        }

    }


    /**
     * get请求, 带上请求头
     * @param requestDto
     * @param token 登录token
     */
    public GetExampleDataDto getExampleWithHeader(GetExampleRequestDto requestDto, String token){
        String url=SERVER_PREFIX+"/get-example?userId={userId}&age={age}";
        try{
            //请求参数
            Map vars=(JSONObject)JSON.toJSON(requestDto);
            //一般在请求头的cookie带上登录token
            HttpCookie tokenCookie=new HttpCookie("token", token);
            HttpHeaders headers=new HttpHeaders();
            headers.add(HttpHeaders.COOKIE, tokenCookie.toString());
            HttpEntity requestEntity=new HttpEntity(headers);

            ResponseEntity<String>  entity=restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class, vars);
            Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
            GetExampleDataDto dataDto=getData(entity.getBody(), GetExampleDataDto.class);
            return dataDto;
        }catch (Exception e){
            String message="请求url: "+url+"出错";
            log.error(message, e);
            log.error("请求参数: {}", JSON.toJSON(requestDto));
            throw new RuntimeException(message, e);
        }

    }




    /**
     * post请求
     * @param requestDto
     */
    public PostExampleDataDto postExample(PostExampleRequestDto requestDto){
        String url=SERVER_PREFIX+"/post-example";
        try{
            //请求参数
            HttpEntity httpEntity=new HttpEntity(requestDto, createJsonHeader());
            ResponseEntity<String>  entity=restTemplate.postForEntity(url, httpEntity, String.class);
            Assert.state(entity.getStatusCode()==HttpStatus.OK, "状态码不等于200");
            PostExampleDataDto dataDto=getData(entity.getBody(), PostExampleDataDto.class);
            return dataDto;
        }catch (Exception e){
            String message="请求url: "+url+"出错";
            log.error(message, e);
            log.error("请求参数: {}", JSON.toJSON(requestDto));
            throw new RuntimeException(message, e);
        }

    }

    private HttpHeaders createJsonHeader(){
        HttpHeaders headers=new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return headers;
    }

    private <T> T getData(String responseString, Class<T> clazz){
        StringDataResponseDto responseDto=JSONObject.parseObject(responseString)
                .toJavaObject(StringDataResponseDto.class);
        if(responseDto.getCode()!=0){
            throw new RuntimeException("code不等于0, 值为["+responseDto.getCode()+"]," +
                    " message=["+responseDto.getMessage()+"]");
        }
        String stringData=responseDto.getData();
        return JSONObject.parseObject(stringData).toJavaObject(clazz);
    }


    @Data
    private static class StringDataResponseDto extends ResponseDto<String> {

    }

}
